package com.yunke.util;

import lombok.extern.slf4j.Slf4j;

/**
 * 云科地理位置工具类
 * 
 * @author yunke
 * @since 2024-01-01
 */
@Slf4j
public class YunkeLocationUtil {

    /**
     * 地球半径（单位：公里）
     */
    private static final double EARTH_RADIUS = 6371.0;

    /**
     * 计算两个地理坐标之间的距离（使用Haversine公式）
     * 
     * @param lat1 第一个点的纬度
     * @param lon1 第一个点的经度
     * @param lat2 第二个点的纬度
     * @param lon2 第二个点的经度
     * @return 距离（单位：公里）
     */
    public static double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
        try {
            // 将角度转换为弧度
            double lat1Rad = Math.toRadians(lat1);
            double lon1Rad = Math.toRadians(lon1);
            double lat2Rad = Math.toRadians(lat2);
            double lon2Rad = Math.toRadians(lon2);
            
            // 计算纬度和经度的差值
            double deltaLat = lat2Rad - lat1Rad;
            double deltaLon = lon2Rad - lon1Rad;
            
            // Haversine公式
            double a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) +
                      Math.cos(lat1Rad) * Math.cos(lat2Rad) *
                      Math.sin(deltaLon / 2) * Math.sin(deltaLon / 2);
            
            double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
            
            // 计算距离
            double distance = EARTH_RADIUS * c;
            
            return Math.round(distance * 100.0) / 100.0; // 保留两位小数
        } catch (Exception e) {
            log.error("计算地理距离失败: lat1={}, lon1={}, lat2={}, lon2={}", lat1, lon1, lat2, lon2, e);
            return Double.MAX_VALUE;
        }
    }

    /**
     * 计算两个地理坐标之间的距离（字符串参数）
     * 
     * @param lat1 第一个点的纬度
     * @param lon1 第一个点的经度
     * @param lat2 第二个点的纬度
     * @param lon2 第二个点的经度
     * @return 距离（单位：公里）
     */
    public static double calculateDistance(String lat1, String lon1, String lat2, String lon2) {
        try {
            double latitude1 = Double.parseDouble(lat1);
            double longitude1 = Double.parseDouble(lon1);
            double latitude2 = Double.parseDouble(lat2);
            double longitude2 = Double.parseDouble(lon2);
            
            return calculateDistance(latitude1, longitude1, latitude2, longitude2);
        } catch (NumberFormatException e) {
            log.error("地理坐标格式错误: lat1={}, lon1={}, lat2={}, lon2={}", lat1, lon1, lat2, lon2, e);
            return Double.MAX_VALUE;
        }
    }

    /**
     * 验证经纬度坐标是否有效
     * 
     * @param latitude  纬度
     * @param longitude 经度
     * @return 是否有效
     */
    public static boolean isValidCoordinate(double latitude, double longitude) {
        return latitude >= -90 && latitude <= 90 && longitude >= -180 && longitude <= 180;
    }

    /**
     * 验证经纬度坐标字符串是否有效
     * 
     * @param latitude  纬度字符串
     * @param longitude 经度字符串
     * @return 是否有效
     */
    public static boolean isValidCoordinate(String latitude, String longitude) {
        try {
            double lat = Double.parseDouble(latitude);
            double lon = Double.parseDouble(longitude);
            return isValidCoordinate(lat, lon);
        } catch (NumberFormatException e) {
            return false;
        }
    }

    /**
     * 根据中心点和半径计算边界框
     * 
     * @param centerLat 中心点纬度
     * @param centerLon 中心点经度
     * @param radiusKm  半径（公里）
     * @return 边界框 [minLat, minLon, maxLat, maxLon]
     */
    public static double[] calculateBoundingBox(double centerLat, double centerLon, double radiusKm) {
        // 1公里对应的纬度差
        double latDelta = radiusKm / 111.0;
        
        // 1公里对应的经度差（根据纬度调整）
        double lonDelta = radiusKm / (111.0 * Math.cos(Math.toRadians(centerLat)));
        
        double minLat = centerLat - latDelta;
        double maxLat = centerLat + latDelta;
        double minLon = centerLon - lonDelta;
        double maxLon = centerLon + lonDelta;
        
        return new double[]{minLat, minLon, maxLat, maxLon};
    }

    /**
     * 格式化距离显示
     * 
     * @param distanceKm 距离（公里）
     * @return 格式化后的距离字符串
     */
    public static String formatDistance(double distanceKm) {
        if (distanceKm < 1) {
            return String.format("%.0fm", distanceKm * 1000);
        } else if (distanceKm < 10) {
            return String.format("%.1fkm", distanceKm);
        } else {
            return String.format("%.0fkm", distanceKm);
        }
    }

    /**
     * 解析地址信息获取城市
     * 
     * @param location 地址信息
     * @return 城市名称
     */
    public static String parseCity(String location) {
        if (location == null || location.trim().isEmpty()) {
            return "";
        }
        
        // 简单的城市解析逻辑
        // 实际项目中可以集成地图API进行准确解析
        String[] parts = location.split("[,，\\s]+");
        for (String part : parts) {
            if (part.endsWith("市") || part.endsWith("区") || part.endsWith("县")) {
                return part;
            }
        }
        
        return parts.length > 0 ? parts[0] : location;
    }
} 